///*
// * To change this template, choose Tools | Templates
// * and open the template in the editor.
// */
//package nodes;
//
//import java.io.IOException;
//import java.util.Random;
//
///**
// *
// * @author Diego
// */
//public class Main {
//
//    static int TRACE = 1;             /* for my debugging */
//
//    int YES = 1;
//    int NO = 0;
//
//    //Cria o pacote
//    public void creatertpkt(rtpkt initrtpkt, int srcid, int destid, int[] mincosts) {
//        int i;
//        initrtpkt.setSourceid(srcid);
//        initrtpkt.setDestid(destid);
//        for (i = 0; i < 4; i++) {
//            initrtpkt.mincost[i] = mincosts[i];
//        }
//    }
//    /*****************************************************************
//     ***************** NETWORK EMULATION CODE STARTS BELOW ***********
//    The code below emulates the layer 2 and below network environment:
//    - emulates the tranmission and delivery (with no loss and no
//    corruption) between two physically connected nodes
//    - calls the initializations routines rtinit0, etc., once before
//    beginning emulation
//
//    THERE IS NOT REASON THAT ANY STUDENT SHOULD HAVE TO READ OR UNDERSTAND
//    THE CODE BELOW.  YOU SHOLD NOT TOUCH, OR REFERENCE (in your code) ANY
//    OF THE DATA STRUCTURES BELOW.  If you're interested in how I designed
//    the emulator, you're welcome to look at the code - but again, you should have
//    to, and you defeinitely should not have to modify
//     ******************************************************************/
//    event evlist;  /* the event list */
//
//    float clocktime = (float) 0.000;
//    int FROM_LAYER2 = 2;
//    static int LINK_CHANGE = 10;
//
//    //Metodo Principal
//    public void main(String arg[]) throws IOException {
//        event eventptr;
//
//        init();
//        boolean aux = true;
//        while (true) {
//
//            eventptr = evlist;            /* get next event to simulate */
//            if (eventptr == null) {
//                aux = false;
//            }
//            evlist = evlist.getNext();        /* remove this event from event list */
//            if (evlist != null) {
//                evlist.setPrev(null);
//            }
//            if (TRACE > 1) {
//                System.out.println("MAIN: rcv event, t=" + eventptr.getEvtime() + ", at " + eventptr.getEventity());
//                if (eventptr.getEvtype() == FROM_LAYER2) {
//                    System.out.println(" src: " + eventptr.getRtpktptr().getSourceid());
//                    System.out.println(" dest: " + eventptr.getRtpktptr().getDestid());
//
//
//
//                    System.out.println(" contents: " + eventptr.getRtpktptr().mincost[0] + eventptr.getRtpktptr().mincost[1] + "\n"
//                            + eventptr.getRtpktptr().mincost[2] + " " + eventptr.getRtpktptr().mincost[3]);
//                }
//            }
//            clocktime = eventptr.getEvtime();    /* update time to next event time */
//            if (eventptr.getEvtype() == FROM_LAYER2) {
//                if (eventptr.getEventity() == 0) {
//                    rtupdate0(eventptr.getRtpktptr());
//                } else if (eventptr.getEventity() == 1) {
//                    rtupdate1(eventptr.getRtpktptr());
//                } else if (eventptr.getEventity() == 2) {
//                    rtupdate2(eventptr.getRtpktptr());
//                } else if (eventptr.getEventity() == 3) {
//                    rtupdate3(eventptr.getRtpktptr());
//                } else {
//                    System.out.println("Panic: unknown event entity\n");
//                    return;
//                }
//            } else if (eventptr.getEvtype() == LINK_CHANGE) {
//                if (clocktime < 10001.0) {
//                    linkhandler0(1, 20);
//                    linkhandler1(0, 20);
//                } else {
//                    linkhandler0(1, 1);
//                    linkhandler1(0, 1);
//                }
//            } else {
//                System.out.println("Panic: unknown event type\n");
//                return;
//            }
//            //if (eventptr.getEvtype() == FROM_LAYER2 )
////          free(eventptr->rtpktptr);        /* free memory for packet, if any */
////        free(eventptr);                    /* free memory for event struct   */
//        }
//
//
//        System.out.println("\nSimulator terminated at t=" + clocktime + ", no packets in medium\n");
//    }
//
//    private static void init() throws IOException {
//        int i;
//        float sum;
//        float avg;
//        float jimsrand;
//
//      event evptr;
//
//       System.out.println("Enter TRACE:");
//        TRACE = System.in.read();
//
//        srand(9999);              /* init random number generator */
//        sum = (float) 0.0;                /* test random number generator for students */
//        for (i = 0; i < 1000; i++) {
//            sum = sum + jimsrand();    /* jimsrand() should be uniform in [0,1] */
//        }
//        avg = sum / 1000.0;
//        if (avg < 0.25 || avg > 0.75) {
//            System.out.println("It is likely that random number generation on your machine\n");
//            System.out.println("is different from what this emulator expects.  Please take\n");
//            System.out.println("a look at the routine jimsrand() in the emulator code. Sorry. \n");
//            return;
//        }
//
//        clocktime = (float) 0.0;                /* initialize time to 0.0 */
//        rtinit0();
//        rtinit1();
//        rtinit2();
//        rtinit3();
//
//        /* initialize future link changes */
//        if (LINKCHANGES == 1) {
//            evptr = new event();
//
//            evptr.setEvtime((float) 10000.0);
//            evptr.setEvtype(LINK_CHANGE);
//            evptr.setEventity(-1);
//            evptr.setRtpktptr(null);
//            insertevent(evptr);
//            evptr = new event();
//            evptr.setEvtype(LINK_CHANGE);
//            evptr.setEvtime(20000.0);
//            evptr.setRtpktptr(null);
//            insertevent(evptr);
//        }
//
//    }
//
//    /****************************************************************************/
//    /* jimsrand(): return a float in range [0,1].  The routine below is used to */
//    /* isolate all random number generation in one location.  We assume that the*/
//    /* system-supplied rand() function return an int in therange [0,mmm]        */
//    /****************************************************************************/
//    private float jimsrand() {
//        double mmm = 2147483647;   /* largest int  - MACHINE DEPENDENT!!!!!!!!   */
//        float x;                   /* individual students may need to change mmm */
//
//        /*
//        troquei isso
//         *  x = rand()/mmm;
//         * pelo random abaixo
//         */
//        Random random = new Random();
//        int rand = random.nextInt();
//
//        x = (float) (rand / mmm);  /* x should be uniform in [0,1] */
//
//        return (x);
//    }
//
//    /********************* EVENT HANDLINE ROUTINES *******/
//    /*  The next set of routines handle the event list   */
//    /*****************************************************/
//    private void insertevent(event p_param) {
//        event p = new event();
//        event q = new event();
//        event qold = new event();
//
//        if (TRACE > 3) {
//            System.out.println("            INSERTEVENT: time is " + clocktime);
//            System.out.println("            INSERTEVENT: future time will be " + p.getEvtime());
//        }
//
//        q = evlist;     /* q points to header of list in which p struct inserted */
//        if (q == null) {   /* list is empty */
//            evlist = p; // temos que ver isso depois... acho q nao pode por encapsulamento fazer isso...
//            p.setNext(null);
//            p.setPrev(null);
//        } else {
//
//            for (qold = q; q != null && p.getEvtime() > q.getEvtime(); q = q.getNext()) {
//                qold = q;
//            }
//            if (q == null) {   /* end of list */
//                // tem q confirmar isso aqui q eu fiz depois...
//                // pelo q eu entendi, tem q modificar o next e o prev...
//                qold.setNext(p);
//                p.setPrev(qold);
//                p.setNext(null);
//            } else if (q == evlist) { /* front of list */
//                p.setNext(evlist);
//                p.setPrev(null);
//                p.getNext().setPrev(p);
//                evlist = p;
//            } else {     /* middle of list */
//                p.setNext(q);
//                p.setPrev(q.getPrev());
//                q.getPrev().setNext(p);
//                q.setPrev(p);
//            }
//        }
//    }
//
//    private void printevlist() {
//
//        event q = new event();
//        System.out.println("--------------\nEvent List Follows: ");
//        for (q = evlist; q != null; q = q.getNext()) {
//            System.out.println("Event time: " + q.getEvtime() + ", type: " + q.getEvtype() + "entity: " + q.getEventity());
//        }
//        System.out.println("--------------");
//    }
//
//    /************************** TOLAYER2 ***************/
//    private void tolayer2(rtpkt packetParam) {
//
//        rtpkt packet = new rtpkt();
//
//
//        rtpkt mypktptr = new rtpkt();
//        event evptr = new event();
//        event q = new event();
//
//        float jimsrand;
//        float lastime;
//        int i;
//        jimsrand = jimsrand();
//        lastime = 0;
//        i = 0;
//        int[][] connectcosts = new int[4][4];
//
//        /* initialize by hand since not all compilers allow array initilization */
//        connectcosts[0][0] = 0;  connectcosts[0][1] = 1;   connectcosts[0][2] = 3;  connectcosts[0][3] = 7;
//        connectcosts[1][0] = 1;  connectcosts[1][1] = 0;   connectcosts[1][2] = 1;  connectcosts[1][3] = 999;
//        connectcosts[2][0] = 3;  connectcosts[2][1] = 1;   connectcosts[2][2] = 0;  connectcosts[2][3] = 2;
//        connectcosts[3][0] = 7;  connectcosts[3][1] = 999; connectcosts[3][2] = 2;  connectcosts[3][3] = 0;
//
//        /* be nice: check if source and destination id's are reasonable */
//        if (packet.getSourceid() < 0 || packet.getSourceid() > 3) {
//            System.out.println("WARNING: illegal source id in your packet, ignoring packet!");
//            return;
//        }
//
//        if (packet.getDestid() < 0 || packet.getDestid() > 3) {
//            System.out.println("WARNING: illegal dest id in your packet, ignoring packet!");
//            return;
//        }
//
//        if (packet.getSourceid() == packet.getDestid()) {
//            System.out.println("WARNING: source and destination id's the same, ignoring packet!");
//            return;
//        }
//
//        if (connectcosts[packet.getSourceid()][packet.getDestid()] == 999) {
//            System.out.println("WARNING: source and destination not connected, ignoring packet!");
//            return;
//        }
//
//        /* make a copy of the packet student just gave me since he/she may decide */
//        /* to do something with the packet after we return back to him/her */
//        //mypktptr = (struct rtpkt *) malloc(sizeof(struct rtpkt));
//        mypktptr.setSourceid(packet.getSourceid());
//        mypktptr.setDestid(packet.getDestid());
//
//        for (i = 0; i < 4; i++) {
//            mypktptr.mincost[i] = packet.mincost[i];
//        }
//
//        if (TRACE > 2) {
//            System.out.println("    TOLAYER2: source: " + mypktptr.getSourceid() + ", dest: " + mypktptr.getDestid() + "              costs:");
//
//            for (i = 0; i < 4; i++) {
//                System.out.println(mypktptr.mincost[i]);
//            }
//            System.out.println();
//        }
//
//        /* create future event for arrival of packet at the other side */
//        //evptr = (struct event *)malloc(sizeof(struct event));
//        evptr.setEvtype(FROM_LAYER2);   /* packet will pop out from layer3 */
//        evptr.setEventity(packet.getDestid()); /* event occurs at other entity */
//        evptr.setRtpktptr(mypktptr);       /* save ptr to my copy of packet */
//
//        /* finally, compute the arrival time of packet at the other end.
//        medium can not reorder, so make sure packet arrives between 1 and 10
//        time units after the latest arrival time of packets
//        currently in the medium on their way to the destination */
//        lastime = clocktime;
//
//        for (q = evlist; q != null; q = q.getNext()) {
//            if ((q.getEvtype() == FROM_LAYER2 && q.getEventity() == evptr.getEventity())) {
//                lastime = q.getEvtime();
//            }
//
//            evptr.setEvtime(lastime + 2 * jimsrand);
//
//
//            if (TRACE > 2) {
//                System.out.println("    TOLAYER2: scheduling arrival on other side");
//            }
//
//            insertevent(evptr);
//        }
//
//    }
//}
